package com.xhwl.centiotdata.suppliersystem.eesd.lanju;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.constant.EesdConstant;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.dto.eesd.EesdEnvConfigDTO;
import com.xhwl.centiotdata.pojo.enums.alarm.LanJuAlarmEnum;
import com.xhwl.centiotdata.utils.SpringContextUtils;
import com.xhwl.common.constant.cent.alarm.AlarmConstant;
import com.xhwl.common.dto.cent.iotdata.lanju.LanJuEnvRespDTO;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import com.xhwl.common.pojo.cent.bi.DwdFactEnvironmentMetrics;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;


/**
 * @author guanyucun
 */
@Slf4j
public class LanjuApiUtil {

    private static final String TOPIC = AlarmConstant.ROMA_TOPIC;

    /**
     * 蓝居获取实时数据&在离线状态
     */
    public static List<DwdFactEnvironmentMetrics> pullEnvRecord(DeviceProjSupplierCategory config) {
        List<DwdFactEnvironmentMetrics> list = new ArrayList<>();
        try {
            JSONObject properties = config.getProperties();
            Integer productId = config.getProductId();
            Integer projectId = config.getProjectId();

            EesdEnvConfigDTO eesdEnvConfigDTO = JSON.toJavaObject(properties, EesdEnvConfigDTO.class);
            eesdEnvConfigDTO.setProjectId(projectId);
            eesdEnvConfigDTO.setProductId(productId);
            /**
             * url:http://122.112.234.240:9007/monitor/devices/real/25278018/all/0
             *
             * 下面是需要配置存在的参数
             * host:http://122.112.234.240:9007
             * realTimeDataUrl:/monitor/devices/real/{deviceId}/all/0
             * deviceId:25278018
             * deviceListUrl:/device/info/
             */
            String host = eesdEnvConfigDTO.getEnvConfigHost();
            String realTimeDataUrl = eesdEnvConfigDTO.getRealTimeDataUrl();
            String deviceListUrl = eesdEnvConfigDTO.getDeviceListUrl();
            String url = host + realTimeDataUrl;
            String deviceId = eesdEnvConfigDTO.getDeviceId();
            // deviceId可以为多个设备id，中间用英文,逗号相隔 例如："deviceId": "25278018,25278515"
            url = url.replace("{deviceId}", deviceId);
            org.apache.http.HttpResponse result = HttpUtils.doGet(url, null, null, new HashMap<>(), new HashMap<>());
            List<LanJuEnvRespDTO> data = null;
            if (result.getStatusLine().getStatusCode() == EesdConstant.SUCCESS_200_CODE) {
                String res = EntityUtils.toString(result.getEntity());
                Map<String, Object> map = JSON.parseObject(res);
                data = JSON.parseArray(JSON.toJSONString(map.get("data")), LanJuEnvRespDTO.class);
            }
            if (CollectionUtils.isEmpty(data)) {
                return list;
            }

            LocalDateTime now = LocalDateTime.now();
            // 根据每个设备id查询设备状态
            for (LanJuEnvRespDTO envRespDTO : data) {
                DwdFactEnvironmentMetrics dwdFactEnvironmentMetrics = new DwdFactEnvironmentMetrics();
                dwdFactEnvironmentMetrics.setProjectId(projectId);
                dwdFactEnvironmentMetrics.setProductId(productId);

                String deviceID = envRespDTO.getDeviceID();
                dwdFactEnvironmentMetrics.setDeviceId(deviceID);
                String deviceUrl = host + deviceListUrl + deviceID;
                org.apache.http.HttpResponse deviceResult = HttpUtils.doGet(deviceUrl, null, null, new HashMap<>(), new HashMap<>());
                String online = null;
                if (deviceResult.getStatusLine().getStatusCode() == EesdConstant.SUCCESS_200_CODE) {
                    String deviceRes = EntityUtils.toString(deviceResult.getEntity());
                    Map<String, Object> map = JSON.parseObject(deviceRes);
                    JSONObject statusData = (JSONObject) map.get("data");
                    online = statusData.getString("is_online");
                }
                if (!StringUtils.isEmpty(online) && online.equals(EesdConstant.ONLINE_STR_STATUS)) {
                    dwdFactEnvironmentMetrics.setDeviceStatus(EesdConstant.ONLINE_STATUS);
                } else {
                    dwdFactEnvironmentMetrics.setDeviceStatus(EesdConstant.OFFLINE_STATUS);
                }
                dwdFactEnvironmentMetrics.setName(envRespDTO.getDeviceID());
                /**
                 * 温度&湿度互斥
                 */
                Double temp;
                if (!ObjectUtils.isEmpty(envRespDTO.getTEMP())) {
                    temp = envRespDTO.getTEMP();
                } else {
                    temp = envRespDTO.getSOTEMP();
                }

                Double humidity;
                if (!ObjectUtils.isEmpty(envRespDTO.getHUMI())) {
                    humidity = envRespDTO.getHUMI();
                } else {
                    humidity = envRespDTO.getSOHUMI();
                }

                dwdFactEnvironmentMetrics.setTemp(temp);
                if (!ObjectUtils.isEmpty(temp)) {
                    if (19 <= temp && temp <= 27) {
                        dwdFactEnvironmentMetrics.setTempCategory("舒适");
                    } else {
                        dwdFactEnvironmentMetrics.setTempCategory("不舒适");
                    }
                }
                dwdFactEnvironmentMetrics.setHumidity(humidity);
                if (!ObjectUtils.isEmpty(humidity)) {
                    if (30 <= humidity && humidity <= 85) {
                        dwdFactEnvironmentMetrics.setHumidityCategory("舒适");
                    } else {
                        dwdFactEnvironmentMetrics.setHumidityCategory("不舒适");
                    }
                }
                Double pm25 = envRespDTO.getPM25();
                dwdFactEnvironmentMetrics.setPm2p5(pm25);
                if (!ObjectUtils.isEmpty(pm25)) {
                    if (pm25 <= 35) {
                        dwdFactEnvironmentMetrics.setPm2p5Category("非常好");
                    } else if (35 < pm25 && pm25 <= 75) {
                        dwdFactEnvironmentMetrics.setPm2p5Category("好");
                    } else if (75 < pm25 && pm25 <= 115) {
                        dwdFactEnvironmentMetrics.setPm2p5Category("良");
                    } else if (115 < pm25 && pm25 <= 150) {
                        dwdFactEnvironmentMetrics.setPm2p5Category("轻微");
                    } else if (pm25 >= 250) {
                        dwdFactEnvironmentMetrics.setPm2p5Category("严重");
                    }
                }

                Double pm10 = envRespDTO.getPM10();
                dwdFactEnvironmentMetrics.setPm10(pm10);
                if (!ObjectUtils.isEmpty(pm10)) {
                    if (pm10 <= 35) {
                        dwdFactEnvironmentMetrics.setPm10Category("非常好");
                    } else if (35 < pm10 && pm10 <= 75) {
                        dwdFactEnvironmentMetrics.setPm10Category("好");
                    } else if (75 < pm10 && pm10 <= 115) {
                        dwdFactEnvironmentMetrics.setPm10Category("良");
                    } else if (115 < pm10 && pm10 <= 150) {
                        dwdFactEnvironmentMetrics.setPm10Category("轻微");
                    } else if (pm10 >= 250) {
                        dwdFactEnvironmentMetrics.setPm10Category("严重");
                    }
                }
                Double noise = envRespDTO.getNOISE();
                dwdFactEnvironmentMetrics.setNoise(noise);
                if (!ObjectUtils.isEmpty(noise)) {
                    if (0 <= noise && noise < 50) {
                        dwdFactEnvironmentMetrics.setNoiseCategory("优");
                    } else if (50 <= noise && noise < 70) {
                        dwdFactEnvironmentMetrics.setNoiseCategory("良");
                    } else if (70 <= noise && noise < 72) {
                        dwdFactEnvironmentMetrics.setNoiseCategory("轻度噪音污染");
                    } else if (72 <= noise && noise < 75) {
                        dwdFactEnvironmentMetrics.setNoiseCategory("中度噪音污染");
                    } else if (noise >= 75) {
                        dwdFactEnvironmentMetrics.setNoiseCategory("重度噪音污染");
                    }
                }

                Double ws = envRespDTO.getWS();
                dwdFactEnvironmentMetrics.setWindSpeed(ws);
                if (!ObjectUtils.isEmpty(ws)) {
                    if (0.0 <= ws && ws < 0.2) {
                        dwdFactEnvironmentMetrics.setWindCategory("无风");
                    } else if (0.2 <= ws && ws < 10.8) {
                        dwdFactEnvironmentMetrics.setWindCategory("和风");
                    } else if (10.8 <= ws && ws < 20.8) {
                        dwdFactEnvironmentMetrics.setWindCategory("大风");
                    } else if (20.8 <= ws && ws < 32.7) {
                        dwdFactEnvironmentMetrics.setWindCategory("狂风");
                    } else if (ws >= 32.7) {
                        dwdFactEnvironmentMetrics.setWindCategory("飓风");
                    }
                }
                dwdFactEnvironmentMetrics.setCh2o(envRespDTO.getCH2O());
                dwdFactEnvironmentMetrics.setCo2(envRespDTO.getCO2());
                dwdFactEnvironmentMetrics.setVoc(envRespDTO.getVOC());
                dwdFactEnvironmentMetrics.setLight(envRespDTO.getLUX());
                dwdFactEnvironmentMetrics.setNai(envRespDTO.getNOI());

                Double h2S = envRespDTO.getH2S();

                dwdFactEnvironmentMetrics.setH2s(h2S);
                if (!ObjectUtils.isEmpty(h2S)) {
                    if (h2S < 2) {
                        dwdFactEnvironmentMetrics.setH2sCategory("正常");
                    } else if (h2S >= 2) {
                        dwdFactEnvironmentMetrics.setH2sCategory("超标");
                    }
                }
                Double nh3 = envRespDTO.getNH3();
                dwdFactEnvironmentMetrics.setNh3(nh3);
                if (!ObjectUtils.isEmpty(nh3)) {
                    if (nh3 < 20) {
                        dwdFactEnvironmentMetrics.setNh3Category("正常");
                    } else if (nh3 >= 20) {
                        dwdFactEnvironmentMetrics.setNh3Category("超标");
                    }
                }
                if (temp != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.TEMP.getCode(), temp);
                }
                if (humidity != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.HUMI.getCode(), humidity);
                }
                if (pm25 != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.PM25.getCode(), pm25);
                }
                if (pm10 != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.PM10.getCode(), pm10);
                }
                if (noise != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.NOISE.getCode(), noise);
                }
                if (ws != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.WS.getCode(), ws);
                }
                if (nh3 != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.NH3.getCode(), nh3);
                }
                if (h2S != null) {
                    sendAlarm(projectId, Integer.valueOf(envRespDTO.getDeviceID()), LanJuAlarmEnum.H2S.getCode(), h2S);
                }
                dwdFactEnvironmentMetrics.setPh(envRespDTO.getSPH());
                dwdFactEnvironmentMetrics.setObsTime(now);
                list.add(dwdFactEnvironmentMetrics);
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(envRespDTO);
            }
        } catch (Exception e) {
            log.error("蓝居获取实时数据: 失败 {}", e.getMessage());
        }
        return list;
    }

    /**
     * 发送告警
     *
     * @param projectId
     * @param deviceId  中台设备id
     * @param alarmCode 告警code
     */
    private static void sendAlarm(Integer projectId, Integer deviceId, String alarmCode, Double threshold) {

        AlarmManagement alarmManagement = new AlarmManagement();
        //组装公共部分数据
        alarmManagement.setProjectId(projectId);
        alarmManagement.setAlarmTime(new Date());
        alarmManagement.setDeviceId(deviceId);
        alarmManagement.setAlarmInventoryCode(alarmCode);
        alarmManagement.setThreshold(new BigDecimal(threshold).setScale(2, RoundingMode.HALF_UP));
        log.info("发出告警: {}", JSON.toJSONString(alarmManagement));
        GeneralProducer generalProducer = SpringContextUtils.getBean(GeneralProducer.class);
        generalProducer.send(TOPIC, alarmManagement);
    }
}
